package cn.shop.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.function.Supplier;

/**
 * 日期时间字符串表示转换便利类。
 * 
 * @author zhy
 *
 */
@SuppressWarnings("unused")
public class DateUtils {
	
	/**
	 * 字符串转为LocalDate。如果字符串为空或不符合格式，返回null。
	 */
	public static LocalDate toDate(String value) {
		LocalDate date = null;
		if (value != null && !value.isEmpty()) {
			try {
				date = LocalDate.parse(value);
			} catch (Exception e) {
				// ignore;
			}
		}
		return date;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成LocalDate，返回转成的LocalDate，否则返回null。
	 */
	public static LocalDate toDate(Supplier<String> supplier) {
		return toDate(supplier.get());
	}
	
	/**
	 * 字符串转为LocalTime。如果字符串为空或不符合格式，返回null。
	 */
	public static LocalTime toTime(String value) {
		LocalTime time = null;
		if (value != null && !value.isEmpty()) {
			try {
				time = LocalTime.parse(value);
			} catch (Exception e) {
				// ignore
			}
		}
		return time;
	}
	
	/**
	 * 如果supplier提供的字符串可以转成LocalTime，返回转成的LocalTime，否则返回null。
	 */
	public static LocalTime toTime(Supplier<String> supplier) {
		return toTime(supplier.get());
	}
	
	
	/**
	 * 字符串转为LocalDateTime。如果字符串为空或不符合格式，返回null。
	 */
	public static LocalDateTime toDateTime(String value) {
		LocalDateTime datetime = null;
		if (value != null && !value.isEmpty()) {
			try {
				datetime = LocalDateTime.parse(value);
			} catch (Exception e) {
				// ignore
			}
		}
		return datetime;
	}

	/**
	 * 如果supplier提供的字符串可以转成LocalDateTime，返回转成的LocalDateTime，否则返回null。
	 *
	 * @param supplier 提供需要转换的字符串
	 * @return 如果成功，转换成的LocalDateTime，否则null
	 */
	public static LocalDateTime toDateTime(Supplier<String> supplier) {
		return toDateTime(supplier.get());
	}
	
	/**
	 * 将纪元毫秒数转为本地日期时间。
	 * 
	 * @param epochMilli UNIX纪元毫秒数
	 * @return 本地日期时间
	 */
	public static LocalDateTime ofEpochMilli(long epochMilli) {
		return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZonedDateTime.now().getZone());
	}

	/**
	 * 将本地日期时间转为纪元毫秒数。
	 *
	 * @param time 本地日期时间
	 * @return UNIX纪元毫秒数
	 */
	public static long toEpochMilli(LocalDateTime time) {
		if (time == null) {
			return 0L;
		}
		return time.toEpochSecond(ZonedDateTime.now().getOffset());
	}

	/**
	 * 将LocalDateTime字符串转为纪元毫秒数。
	 *
	 * @param value LocalDateTime字符串
	 * @return UNIX纪元毫秒数
	 */
	public static long toEpochMilli(String value) {
		LocalDateTime time = toDateTime(value);
		return toEpochMilli(time);
	}

	/**
	 * 如果date不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param date 要转换的日期
	 * @return 如果成功，date转成的字符串，否则null
	 */
	public static String fromDate(LocalDate date) {
		return date == null ? null : date.format(DateTimeFormatter.ISO_LOCAL_DATE);
	}
	
	/**
	 * 如果time不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param time 要转换的时间
	 * @return 如果成功，time转成的字符串，否则null
	 */
	public static String fromTime(LocalTime time) {
		return time == null ? null : time.format(DateTimeFormatter.ISO_LOCAL_TIME);
	}
	
	/**
	 * 如果datetime不是null，返回其字符串表示，否则返回null。
	 * 
	 * @param datetime 要转换的日期时间
	 * @return 如果成功，datetime转成的字符串，否则null
	 */
	public static String fromDateTime(LocalDateTime datetime) {
		return datetime == null ? null : datetime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
	}
	
	/**
	 * 将纪元毫秒数转成日期时间的字符串表示。
	 * 
	 * @param epochMilli 纪元毫秒数
	 * @return 纪元毫秒数对应日期时间的字符串表示
	 */
	public static String fromEpochMilli(long epochMilli) {
		return fromDateTime(ofEpochMilli(epochMilli));
	}
	
}
